package com.smsc.headend.connector.netty;

import com.smsc.headend.connector.netty.initializer.AnsiInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.AdaptiveRecvByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.concurrent.DefaultThreadFactory;
import lombok.extern.slf4j.Slf4j;


@Slf4j
public class AnsiServer {
    ServerBootstrap bootstrap;
    EventLoopGroup worker;
    EventLoopGroup boss;

    int port;

    public AnsiServer(int port) {
        this.port = port;
    }

    public void start() throws InterruptedException {
        bootstrap = new ServerBootstrap();
        log.info("start init NioServer : {}", port);

//        boss = new EpollEventLoopGroup(2, new DefaultThreadFactory("boss", true));
//        worker = new EpollEventLoopGroup(4, new DefaultThreadFactory("worker", true));
        boss = new NioEventLoopGroup(2, new DefaultThreadFactory("boss", true));
        worker = new NioEventLoopGroup(4, new DefaultThreadFactory("worker", true));

        bootstrap.group(boss, worker).handler(new LoggingHandler(LogLevel.DEBUG)).channel(NioServerSocketChannel.class)
                .childHandler(new AnsiInitializer());
        //标识当服务器请求处理线程全满时，用于临时存放已完成三次握手的请求的队列的最大长度
        bootstrap.option(ChannelOption.SO_BACKLOG, 1024)
                .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator())
                .childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);

        ChannelFuture channelFuture = bootstrap.bind(port).sync();
        if (channelFuture.isSuccess()) {
            log.info("netty TCP Ansi Server at port {} start success", port);
        }
    }

    public void stop() {
        try {
            this.worker.shutdownGracefully().await();
            this.boss.shutdownGracefully().await();
        } catch (InterruptedException e) {
            log.error("TCP Server stopped error", e);
        }
        this.log.info("TCP Server stopped...");
    }

}
